#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <termios.h> /*PPSIX?????????*/
#include <fcntl.h>
#include <error.h>

#include "t_types.h"
#include "hal/hal_uart.h"
#include "common/config.h"
#include "common/lock.h"
#include "userLog.h"
#include "uv.h"
#include "CxlUtil.h"
#include <sys/select.h>

#define HAL_UART_CFG_FILE T_CONFIG_ROOT_PATH "/hal_uart.ini"
#define HAL_UART_RECV_BUF_LEN (1024 * 8)
#define HAL_UART_DATA_BITS (8)
#define HAL_UART_STOP_BITS (1)
#define HAL_UART_PARITY 'n'
int Console_CmdAdd(char *pCmd, CONSOLE_CMD_CB cb);
T_INT32 COMM_HexStrToByte(const T_CHAR *source, T_UINT8 *dest, T_INT32 sourceLen);

typedef struct _HAL_UART_CONTEXT_S
{
	int as32DevFd[HAL_UART_MAX_CHANNEL];
	T_CALLBACK afnCallBack[HAL_UART_MAX_CHANNEL];
	T_LOCK_HANDLE ahSendLock[HAL_UART_MAX_CHANNEL];
	T_LOCK_HANDLE ahRecvLock[HAL_UART_MAX_CHANNEL];
	int s32Run;
} HAL_UART_CONTEXT_S;

static HAL_UART_CONFIG_S gsstHalUartCfgs;
static HAL_UART_CONTEXT_S *pstHalUartCtx = NULL;
static int gss32SndRecvPrint = 0x0;

/*
????????????UART1???/dev/ttymxc0
*/

static CONFIG_RECORD_S astRecords[] =
	{
		{"enable0", &gsstHalUartCfgs.astUartChannel[0].u32Enable, CONFIG_TYPE_UINT32},
		{"devname0", gsstHalUartCfgs.astUartChannel[0].au8DevName, CONFIG_TYPE_STRING},
		{"baudrate0", &gsstHalUartCfgs.astUartChannel[0].u32BaudRate, CONFIG_TYPE_UINT32},
		{"appname0", gsstHalUartCfgs.astUartChannel[0].as8AppName, CONFIG_TYPE_STRING},
		{"enable1", &gsstHalUartCfgs.astUartChannel[1].u32Enable, CONFIG_TYPE_UINT32},
		{"devname1", gsstHalUartCfgs.astUartChannel[1].au8DevName, CONFIG_TYPE_STRING},
		{"baudrate1", &gsstHalUartCfgs.astUartChannel[1].u32BaudRate, CONFIG_TYPE_UINT32},
		{"appname1", gsstHalUartCfgs.astUartChannel[1].as8AppName, CONFIG_TYPE_STRING},
		{"enable2", &gsstHalUartCfgs.astUartChannel[2].u32Enable, CONFIG_TYPE_UINT32},
		{"devname2", gsstHalUartCfgs.astUartChannel[2].au8DevName, CONFIG_TYPE_STRING},
		{"baudrate2", &gsstHalUartCfgs.astUartChannel[2].u32BaudRate, CONFIG_TYPE_UINT32},
		{"appname2", gsstHalUartCfgs.astUartChannel[2].as8AppName, CONFIG_TYPE_STRING},
		{"enable3", &gsstHalUartCfgs.astUartChannel[3].u32Enable, CONFIG_TYPE_UINT32},
		{"devname3", gsstHalUartCfgs.astUartChannel[3].au8DevName, CONFIG_TYPE_STRING},
		{"baudrate3", &gsstHalUartCfgs.astUartChannel[3].u32BaudRate, CONFIG_TYPE_UINT32},
		{"appname3", gsstHalUartCfgs.astUartChannel[3].as8AppName, CONFIG_TYPE_STRING},
		{"enable4", &gsstHalUartCfgs.astUartChannel[4].u32Enable, CONFIG_TYPE_UINT32},
		{"devname4", gsstHalUartCfgs.astUartChannel[4].au8DevName, CONFIG_TYPE_STRING},
		{"baudrate4", &gsstHalUartCfgs.astUartChannel[4].u32BaudRate, CONFIG_TYPE_UINT32},
		{"appname4", gsstHalUartCfgs.astUartChannel[4].as8AppName, CONFIG_TYPE_STRING},
		{"enable5", &gsstHalUartCfgs.astUartChannel[5].u32Enable, CONFIG_TYPE_UINT32},
		{"devname5", gsstHalUartCfgs.astUartChannel[5].au8DevName, CONFIG_TYPE_STRING},
		{"baudrate5", &gsstHalUartCfgs.astUartChannel[5].u32BaudRate, CONFIG_TYPE_UINT32},
		{"appname5", gsstHalUartCfgs.astUartChannel[5].as8AppName, CONFIG_TYPE_STRING},
};

static int _HAL_UART_RecvThread(void *);
static int _CMD_HAL_UART_Test(CONSOLE_CMD_PARAM_S *pParam, char *pAck);
static int _CMD_HAL_UART_SndRecvPrint(CONSOLE_CMD_PARAM_S *pParam, char *pAck);
static int _CMD_HAL_UART_SendHex(CONSOLE_CMD_PARAM_S *pParam, char *pAck);

static int _HAL_UART_setParity(int s32DevFd, unsigned char u8Databits, unsigned char u8Stopbits, unsigned char u8Parity)
{
	struct termios options;
	if (tcgetattr(s32DevFd, &options) != 0)
	{
		LOG_ERROR("Get Uart setting error");
		return -1;
	}
	/*---------------------*/
	/*----------------------*
	  options.c_cflag &= ~CSIZE;
	  options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG );
	  */
	options.c_cflag &= ~CSIZE;
	options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
	options.c_oflag &= ~OPOST; /*liu need , chen del*/

	switch (u8Databits) /*????????��??*/
	{
	case 5:
		options.c_cflag |= CS5;
		break;

	case 6:
		options.c_cflag |= CS6;
		break;
	case 7:
		options.c_cflag |= CS7;
		break;

	case 8:
		options.c_cflag |= CS8;
		break;

	default:
		LOG_ERROR("Unsupported data size: u8Databits=%d", u8Databits);
		return -1;
	}
	switch (u8Parity)
	{
	case 'n':
	case 'N':
		options.c_cflag &= ~PARENB; /* Clear parity enable */
		options.c_iflag &= ~INPCK;	/* Enable parity checking */
		break;

	case 'o':
	case 'O':
		options.c_cflag |= (PARODD | PARENB); /* ???????��??*/
		options.c_iflag |= INPCK;			  /* Disnable parity checking */
		break;

	case 'e':
	case 'E':
		options.c_cflag |= PARENB;	/* Enable parity */
		options.c_cflag &= ~PARODD; /* ?????��??*/
		options.c_iflag |= INPCK;	/* Disnable parity checking */
		break;
#if 0			
		case RS485_MARK:
		case RS485_SPACE:
			options.c_cflag &= ~PARENB;   /* Clear parity enable */
			options.c_iflag &= ~INPCK;     /* Enable parity checking */
			break;
#endif
	case 'S':
	case 's': /*as no parity*/
		options.c_cflag &= ~PARENB;
		options.c_cflag &= ~CSTOPB;
		break;
	default:
		LOG_ERROR("Unsupported parity:u8Parity=%c", u8Parity);
		return -1;
	}

	/* ??????��*/
	switch (u8Stopbits)
	{
	case 1:
		options.c_cflag &= ~CSTOPB;
		break;

	case 15:
		if (u8Databits == 5)
		{
			options.c_cflag |= CSTOPB;
		}
		else
		{
			LOG_ERROR("Unsupported databit =%d , stop bits=%d", u8Databits, u8Stopbits);
			return -1;
		}
		break;

	case 2:
		options.c_cflag |= CSTOPB;
		break;
	default:
		LOG_ERROR("Unsupported stop bits:u8Stopbits=%d", u8Stopbits);
		return -1;
	}

	/* Set input parity option */
	if (u8Parity != 'n')
		options.c_iflag |= INPCK;
	options.c_cc[VTIME] = 150; //150  15 seconds
	options.c_cc[VMIN] = 0;
	/*--------------------*/
	options.c_lflag = 0;
	options.c_lflag &= ICANON;
	options.c_iflag &= IGNPAR;

	options.c_oflag &= ~ONLCR; /*liu need; chen del*/

	/*options.c_oflag &= ONLCR;*/ /*chen need */

	/*----------------*/
	tcflush(s32DevFd, TCIFLUSH); /* Update the options and do it NOW */
	if (tcsetattr(s32DevFd, TCSANOW, &options) != 0)
	{
		LOG_ERROR("SetupSerial 3 error");
		return -1;
	}
	return 0;
}
int gBaudRateArr[] = {B300, B600, B1200, B1800, B2400, B4800, B9600, B19200, B38400, B57600, B115200};
//					    7 		8  	9  	     b 	c  	     d  	e 		 f  	1001  	1002
static int _HAL_UART_setBaudRate(int s32DevFd, unsigned int u32BaudRate)
{
	int iStatus;
	struct termios optTermios;
	int s32BaudRateDef;

	if (u32BaudRate > 115200)
		return -1;

	switch (u32BaudRate)
	{
	case 2400:
	{
		s32BaudRateDef = B2400;
		break;
	}
	case 4800:
	{
		s32BaudRateDef = B4800;
		break;
	}
	case 9600:
	{
		s32BaudRateDef = B9600;
		break;
	}
	case 19200:
	{
		s32BaudRateDef = B19200;
		break;
	}
	case 38400:
	{
		s32BaudRateDef = B38400;
		break;
	}
	case 57600:
	{
		s32BaudRateDef = B57600;
		break;
	}
	case 115200:
	{
		s32BaudRateDef = B115200;
		break;
	}
	default:
	{
		LOG_ERROR("unsupport baudrate:%u", u32BaudRate);
		return -1;
	}
	}

	tcgetattr(s32DevFd, &optTermios);
	tcflush(s32DevFd, TCIOFLUSH);
	cfsetispeed(&optTermios, s32BaudRateDef);
	cfsetospeed(&optTermios, s32BaudRateDef);
	iStatus = tcsetattr(s32DevFd, TCSANOW, &optTermios);
	if (iStatus != 0)
	{
		LOG_ERROR("tcsetattr iFileHandle error!iStatus=%d", iStatus);
		return -1;
	}
	tcflush(s32DevFd, TCIOFLUSH);
	return 0;
}

static int _HAL_UART_DevInit(void)
{
	int i;
	int ret = 0;

	if (!pstHalUartCtx)
	{
		LOG_ERROR("null ptr");
		return -1;
	}

	for (i = 0; i < HAL_UART_MAX_CHANNEL; i++)
	{
		if (!gsstHalUartCfgs.astUartChannel[i].u32Enable)
		{
			continue;
		}
		pstHalUartCtx->as32DevFd[i] = open(gsstHalUartCfgs.astUartChannel[i].au8DevName, O_RDWR);
		if (pstHalUartCtx->as32DevFd[i] < 0)
		{
			LOG_ERROR("open uart %d error, dev name:%s", i, gsstHalUartCfgs.astUartChannel[i].au8DevName);
			pstHalUartCtx->as32DevFd[i] = -1;
		}
		else
		{
			ret = _HAL_UART_setParity(pstHalUartCtx->as32DevFd[i], HAL_UART_DATA_BITS, HAL_UART_STOP_BITS, HAL_UART_PARITY);
			if (ret != 0)
			{
				LOG_ERROR("_HAL_UART_setParity() error, index:%d, devname:%s", i, gsstHalUartCfgs.astUartChannel[i].au8DevName);
			}
			_HAL_UART_setBaudRate(pstHalUartCtx->as32DevFd[i], gsstHalUartCfgs.astUartChannel[i].u32BaudRate);
			if (ret != 0)
			{
				LOG_ERROR("_HAL_UART_setBaudRate() error, index:%d, devname:%s", i, gsstHalUartCfgs.astUartChannel[i].au8DevName);
			}
		}
		LOG_INFO("MSG uart[%d] fd:%d", i, pstHalUartCtx->as32DevFd[i]);
		usleep(10 * 1000);
	}

	return 0;
}
int HAL_UART_Init(void)
{
	int i;
	int s32ThrdIdx = 0;
	char acName[32];

	pstHalUartCtx = (HAL_UART_CONTEXT_S *)malloc(sizeof(HAL_UART_CONTEXT_S));
	if (pstHalUartCtx == NULL)
	{
		LOG_ERROR("can not malloc memory for hal uart context!");
		return -1;
	}
	memset((void *)pstHalUartCtx, 0, sizeof(HAL_UART_CONTEXT_S));

	// lock init
	for (i = 0; i < HAL_UART_MAX_CHANNEL; i++)
	{
		memset(acName, 0, sizeof(acName));
		sprintf(acName, "UartRecvLock%d", i);
		pstHalUartCtx->ahRecvLock[i] = LockCreate(acName);
		if (!pstHalUartCtx->ahRecvLock[i])
		{
			LOG_ERROR("create uart recv lock error");
			return -1;
		}
		memset(acName, 0, sizeof(acName));
		sprintf(acName, "UartSendLock%d", i);
		pstHalUartCtx->ahSendLock[i] = LockCreate(acName);
		if (!pstHalUartCtx->ahSendLock[i])
		{
			LOG_ERROR("create uart send lock error");
			return -1;
		}
	}

	memset(&gsstHalUartCfgs, 0, sizeof(gsstHalUartCfgs));

	Config_LoadFile(HAL_UART_CFG_FILE, astRecords, T_ARRAY_SIZE(astRecords));
	LOG_INFO("devname0:%s,baudrate0:%u", gsstHalUartCfgs.astUartChannel[0].au8DevName, gsstHalUartCfgs.astUartChannel[0].u32BaudRate);

	// init uart
	_HAL_UART_DevInit();

	pstHalUartCtx->s32Run = 1;

	uv_work_t *hal_uart_recvReq = (uv_work_t *)malloc(sizeof(uv_work_t));
	uv_loop_t *loop = getLoop();

	uv_queue_work(loop, hal_uart_recvReq, _HAL_UART_RecvThread, NULL);

	Console_CmdAdd("t-hal-uart-test", _CMD_HAL_UART_Test);
	Console_CmdAdd("t-hal-uart-sndrecvprint", _CMD_HAL_UART_SndRecvPrint);
	Console_CmdAdd("t-hal-uart-sendhex", _CMD_HAL_UART_SendHex);

	return 0;
_error:
	HAL_UART_DeInit();
	return -1;
}

int HAL_UART_DeInit(void)
{
	int i;

	pstHalUartCtx->s32Run = 0;

	if (pstHalUartCtx)
	{
		for (i = 0; i < HAL_UART_MAX_CHANNEL; i++)
		{
			if (pstHalUartCtx->as32DevFd[i] > 0)
			{
				close(pstHalUartCtx->as32DevFd[i]);
				pstHalUartCtx->as32DevFd[i] = -1;
			}
		}
		free((void *)pstHalUartCtx);
	}

	return 0;
}

int HAL_UART_RegisterRecvCallback(int s32Chn, T_CALLBACK fnCb)
{
	if (!pstHalUartCtx)
	{
		LOG_ERROR("hal uart not init");
		return -1;
	}

	if (s32Chn < 0 || s32Chn >= HAL_UART_MAX_CHANNEL)
	{
		LOG_ERROR("invalid s32Chn:%d", s32Chn);
		return -1;
	}

	pstHalUartCtx->afnCallBack[s32Chn] = fnCb;

	return 0;
}
int HAL_UART_unRegisterRecvCallback(int s32Chn)
{
	if (s32Chn < 0 || s32Chn >= HAL_UART_MAX_CHANNEL)
	{
		LOG_ERROR("invalid s32Chn:%d", s32Chn);
		return -1;
	}
	if (pstHalUartCtx)
	{
		pstHalUartCtx->afnCallBack[s32Chn] = NULL;
	}
	return 0;
}

int HAL_UART_Probe(char *ps8AppName)
{
	int i;
	int found = -1;

	if (!ps8AppName)
	{
		LOG_ERROR("null ptr");
		return -1;
	}

	if (!pstHalUartCtx)
	{
		LOG_ERROR("hal uart not init");
		return -1;
	}

	for (i = 0; i < HAL_UART_MAX_CHANNEL; i++)
	{
		if (!strcmp(ps8AppName, gsstHalUartCfgs.astUartChannel[i].as8AppName))
		{
			found = i;
			break;
		}
	}
	if (found < 0)
	{
		LOG_ERROR("uart probe failed for appname:%s", ps8AppName);
		return -1;
	}

	return found;
}

int HAL_UART_Send(int s32Chn, unsigned char *pu8Data, int s32Len)
{
	int s32Ret = 0;

	if (pstHalUartCtx == NULL)
	{
		LOG_ERROR("hal uart context not init");
		return -1;
	}
	if (s32Chn < 0 || s32Chn >= HAL_UART_MAX_CHANNEL)
	{
		LOG_ERROR("hal uart channel num error:%d", s32Chn);
		return -1;
	}
	if (pu8Data == NULL || s32Len <= 0)
	{
		LOG_ERROR("invalid arguments");
		return -1;
	}

	LockEnter(pstHalUartCtx->ahSendLock[s32Chn]);
	s32Ret = write(pstHalUartCtx->as32DevFd[s32Chn], pu8Data, s32Len);
	if (gss32SndRecvPrint & (1 << (s32Chn + 8)))
	{
		LOG_INFO("uart[%d] send len:%d", s32Chn, s32Len);
		// printHex(pu8Data, s32Len);
		hzlog_info(userLog, pu8Data, s32Len / 2);
	}
	LockLeave(pstHalUartCtx->ahSendLock[s32Chn]);

	return s32Ret;
}

int HAL_UART_Recv(int s32Chn, unsigned char *pu8Data, int s32Len)
{
	int s32Ret = 0;

	if (pstHalUartCtx == NULL)
	{
		LOG_ERROR("hal uart context not init");
		return -1;
	}
	if (s32Chn < 0 || s32Chn >= HAL_UART_MAX_CHANNEL)
	{
		LOG_ERROR("hal uart channel num error:%d", s32Chn);
		return -1;
	}
	if (pu8Data == NULL || s32Len <= 0)
	{
		LOG_ERROR("invalid arguments");
		return -1;
	}

	LockEnter(pstHalUartCtx->ahRecvLock[s32Chn]);
	s32Ret = read(pstHalUartCtx->as32DevFd[s32Chn], pu8Data, s32Len);
	LockLeave(pstHalUartCtx->ahRecvLock[s32Chn]);

	return s32Ret;
}

static T_INT32 _HAL_UART_RecvThread(void *pvParam)
{
	int s32MaxFd = 0;
	fd_set fdsRead;
	struct timeval timeOut;
	int i;
	int s32ValidNum = 0;
	int s32Ret = 0;
	unsigned char au8RecvBuff[HAL_UART_RECV_BUF_LEN];
	HAL_UART_CB_PARAM_S stCbParam;

	while (pstHalUartCtx && pstHalUartCtx->s32Run)
	{
#if 0		
		s32ValidNum = 0;
		for(i=0; i<HAL_UART_MAX_CHANNEL; i++)
		{
			if(!gsstHalUartCfgs.astUartChannel[i].u32Enable)
			{
				continue;
			}
			if(pstHalUartCtx->as32DevFd[i] < 0)
			{
				pstHalUartCtx->as32DevFd[i] = open(gsstHalUartCfgs.astUartChannel[i].au8DevName, O_RDWR);
				if(pstHalUartCtx->as32DevFd[i] < 0)
				{
					LOG_ERROR("open uart:%s error", gsstHalUartCfgs.astUartChannel[i].au8DevName);
					continue;
				}
				_HAL_UART_setParity(pstHalUartCtx->as32DevFd[i], 8, 1, 'n');
				_HAL_UART_setBaudRate(pstHalUartCtx->as32DevFd[i], gsstHalUartCfgs.astUartChannel[i].u32BaudRate);
				s32ValidNum++;
			}
		}
		if(s32ValidNum == 0)
		{
			usleep(100*1000);
			continue;
		}
#endif
		timeOut.tv_sec = 5;
		timeOut.tv_usec = 0;
		FD_ZERO(&fdsRead);
		s32MaxFd = 0;
		for (i = 0; i < HAL_UART_MAX_CHANNEL; i++)
		{
			if (pstHalUartCtx->as32DevFd[i] > 0 && pstHalUartCtx->afnCallBack[i])
			{
				FD_SET(pstHalUartCtx->as32DevFd[i], &fdsRead);
				s32MaxFd = pstHalUartCtx->as32DevFd[i] > s32MaxFd ? pstHalUartCtx->as32DevFd[i] : s32MaxFd;
			}
		}
		if (s32MaxFd == 0)
		{
			usleep(100 * 1000);
			continue;
		}
		//LOG_INFO("MSG s32MaxFd:%d", s32MaxFd);
		s32Ret = select(s32MaxFd + 1, &fdsRead, NULL, NULL, &timeOut);
		if (s32Ret < 0)
		{
			LOG_ERROR("uart recv select error");
			usleep(10 * 1000);
			continue;
		}
		else if (s32Ret == 0)
		{
			usleep(10 * 1000);
			//LOG_INFO("MSG uart select timeout");
			continue;
		}
		else
		{
			//console_here;
			for (i = 0; i < HAL_UART_MAX_CHANNEL; i++)
			{
				if (FD_ISSET(pstHalUartCtx->as32DevFd[i], &fdsRead))
				{
					memset(au8RecvBuff, 0, HAL_UART_RECV_BUF_LEN);
					s32Ret = read(pstHalUartCtx->as32DevFd[i], au8RecvBuff, HAL_UART_RECV_BUF_LEN);
					if (s32Ret <= 0)
					{
						LOG_ERROR("uart[%d] read error:0x%x", i, s32Ret);
						close(pstHalUartCtx->as32DevFd[i]);
						pstHalUartCtx->as32DevFd[i] = -1;
						continue;
					}
					if (gss32SndRecvPrint & (1 << i))
					{
						LOG_INFO("MSG id:%d,len:%d", i, s32Ret);
						// printHex(au8RecvBuff, s32Ret);
						hzlog_info(userLog, au8RecvBuff, s32Ret);
					}
					//LOG_INFO("MSG id:%d,len:%d,data:%s", i, s32Ret, au8RecvBuff);
					// callback here
					if (pstHalUartCtx->afnCallBack[i])
					{
						//console_here;
						stCbParam.pu8Buff = au8RecvBuff;
						stCbParam.s32Len = s32Ret;
						pstHalUartCtx->afnCallBack[i]((void *)&stCbParam);
					}
				}
			}
		}
	}
	return 0;
}

static int _HAL_UART_RecvCbTest(void *pvParam)
{
	int i;
	HAL_UART_CB_PARAM_S *pstCbParam = (HAL_UART_CB_PARAM_S *)pvParam;

	if (!pvParam)
	{
		LOG_ERROR("null ptr");
		return -1;
	}

	//console_here;

	LOG_INFO("MSG Recv len:%d, data:%s", pstCbParam->s32Len, pstCbParam->pu8Buff);

	return 0;
}

static int _CMD_HAL_UART_Test(CONSOLE_CMD_PARAM_S *pParam, char *pAck)
{
	char abyHelp[] = "./cmd serialNum(0~5) string\n";
	int nParam = 0;

	if (pParam->nArgsNum != 2)
	{
		sprintf(pAck, "%s", abyHelp);
		return 0;
	}

	nParam = strtoul(pParam->abyArgs[0], NULL, 0);
	if (nParam < 0 || nParam >= HAL_UART_MAX_CHANNEL)
	{
		sprintf(pAck, "error.help:%s\n", abyHelp);
		return 0;
	}

	HAL_UART_RegisterRecvCallback(nParam, _HAL_UART_RecvCbTest);
	usleep(100 * 1000);
	HAL_UART_Send(nParam, pParam->abyArgs[1], strlen(pParam->abyArgs[1]));

	sprintf(pAck, "ok\n");

	return 0;
}

static int _CMD_HAL_UART_SndRecvPrint(CONSOLE_CMD_PARAM_S *pParam, char *pAck)
{
	char abyHelp[] = "./cmd printmask.bit0~7 for recv, bit8~15 for snd\n";
	int nParam = 0;

	if (pParam->nArgsNum != 1)
	{
		sprintf(pAck, "%s", abyHelp);
		return 0;
	}

	gss32SndRecvPrint = strtoul(pParam->abyArgs[0], NULL, 0);

	sprintf(pAck, "ok\n");

	return 0;
}

static int _CMD_HAL_UART_SendHex(CONSOLE_CMD_PARAM_S *pParam, char *pAck)
{
	char abyHelp[] = "./cmd uartnum hexData. ex. 4a4b\n";
	int s32Len = 0;
	char data[32];
	int nParam = 0;

	if (pParam->nArgsNum != 2)
	{
		sprintf(pAck, "%s", abyHelp);
		return 0;
	}

	nParam = strtoul(pParam->abyArgs[0], NULL, 0);

	s32Len = strlen(pParam->abyArgs[1]);
	COMM_HexStrToByte(pParam->abyArgs[1], data, s32Len);
	LOG_INFO("input data len:%d, data:", s32Len);
	// printHex(data, s32Len / 2);
	hzlog_info(userLog, data, s32Len / 2);

	HAL_UART_Send(nParam, data, s32Len / 2);

	sprintf(pAck, "ok\n");
	return 0;
}
